/*
 * Copyright (c) 2016-2017 fulihui.com All right reserved
 * Project: information-core-170307
 * File name: DynamicNavbarServiceImpl.java
 */

package com.fulihui.information.service;

import com.fulihui.information.api.DynamicNavbarService;
import com.fulihui.information.biz.conv.DynamicNavbarConv;
import com.fulihui.information.core.repository.DynamicNavbarRepository;
import com.fulihui.information.dal.dataobj.InfoDynamicNavbarExample;
import com.fulihui.information.dal.dataobj.InfoDynamicNavbarKey;
import com.fulihui.information.dto.DynamicNavbarDTO;
import com.fulihui.information.enums.EAppType;
import com.fulihui.information.enums.EDynamicNavbarOptionType;
import com.fulihui.information.enums.EYesOrNo;
import com.fulihui.information.request.DynamicNavbarQueryPageRequest;
import com.fulihui.information.request.DynamicNavbarQueryRequest;
import com.fulihui.information.request.DynamicNavbarQuerySingleRequest;
import com.fulihui.information.request.DynamicNavbarSaveRequest;
import com.fulihui.information.util.VersionFormat;
import org.near.servicesupport.error.Errors;
import org.near.servicesupport.result.BaseResult;
import org.near.servicesupport.result.TMultiResult;
import org.near.servicesupport.result.TPageResult;
import org.near.servicesupport.result.TSingleResult;
import org.near.servicesupport.util.ServiceAssert;
import org.near.toolkit.common.EnumUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.near.servicesupport.result.ResultBuilder.*;
import static org.near.toolkit.common.StringUtil.isNotBlank;

/**
 * @author Willard.Hu on 2017/3/3 0003.
 */
@Service("dynamicNavbarService")
public class DynamicNavbarServiceImpl implements DynamicNavbarService {
    @Autowired
    private DynamicNavbarRepository dynamicNavbarRepository;

    /**
     * @see DynamicNavbarService#save(DynamicNavbarSaveRequest)
     */
    @Override
    public BaseResult save(DynamicNavbarSaveRequest request) {
        ServiceAssert.isTrue(EnumUtil.inEnum(request.getOsType(), EAppType.class),
                Errors.Commons.REQUEST_PARAMETER_ERROR);
        ServiceAssert.isTrue(EnumUtil.inEnum(request.getOptionType(), EDynamicNavbarOptionType.class),
                Errors.Commons.REQUEST_PARAMETER_ERROR);

        InfoDynamicNavbarKey key = DynamicNavbarConv.tokey(request);
        DynamicNavbarDTO dto = dynamicNavbarRepository.querySingle(key);
        if (dto == null) { // insert
            dynamicNavbarRepository.insert(request);
        } else { // update
            boolean b = dynamicNavbarRepository.update(request);
            if (!b) {
                return fail(Errors.Commons.SYSTEM_ERROR);
            }
        }
        return succ();
    }

    /**
     * @see DynamicNavbarService#delete(DynamicNavbarQuerySingleRequest)
     */
    @Override
    public BaseResult delete(DynamicNavbarQuerySingleRequest request) {
        ServiceAssert.isTrue(EnumUtil.inEnum(request.getOsType(), EAppType.class),
                Errors.Commons.REQUEST_PARAMETER_ERROR);
        InfoDynamicNavbarKey key = DynamicNavbarConv.tokey(request);
        boolean b = dynamicNavbarRepository.delete(key);
        return b ? succ() : fail(Errors.Commons.SYSTEM_ERROR);
    }

    /**
     * @see DynamicNavbarService#querySingle(DynamicNavbarQuerySingleRequest)
     */
    @Override
    public TSingleResult<DynamicNavbarDTO> querySingle(DynamicNavbarQuerySingleRequest request) {
        ServiceAssert.isTrue(EnumUtil.inEnum(request.getOsType(), EAppType.class),
                Errors.Commons.REQUEST_PARAMETER_ERROR);
        InfoDynamicNavbarKey key = DynamicNavbarConv.tokey(request);
        // XXX 低版本向下兼容
        key.setVersion(10000);
        key.setNavbarCode("NAVBAR_1");
        // XXX end
        DynamicNavbarDTO dto = dynamicNavbarRepository.querySingle(key);
        if (dto == null) {
            dto = dynamicNavbarRepository.queryPreviousVersion(request.getOsType(),
                    VersionFormat.atoi(request.getVersion()));
        }
        return succTSingle(dto);
    }

    /**
     * @see DynamicNavbarService#query(DynamicNavbarQueryRequest)
     */
    @Override
    public TMultiResult<DynamicNavbarDTO> query(DynamicNavbarQueryRequest request) {
        InfoDynamicNavbarExample example = new InfoDynamicNavbarExample();
        InfoDynamicNavbarExample.Criteria criteria = example.createCriteria();
        if (isNotBlank(request.getVersion())) { // 支持版本号向下兼容，找最新的版本，这样可以不用每个版本都去维护数据
            criteria.andVersionLessThanOrEqualTo(VersionFormat.atoi(request.getVersion()));
        }
        if (isNotBlank(request.getOsType())) {
            criteria.andOsTypeEqualTo(request.getOsType());
        }
        if (request.getShowState() != null) {
            criteria.andShowStateEqualTo(request.getShowState() ?
                    EYesOrNo.YES.getCode() : EYesOrNo.NO.getCode());
        }
        example.setOrderByClause("version desc");
        List<DynamicNavbarDTO> list = dynamicNavbarRepository.query(example);
        // 有版本号作为查询条件的，获取离查询最近的版本，这样可以不用每个版本都去维护数据
        if (isNotBlank(request.getVersion())) {
            Map<String, DynamicNavbarDTO> tmp = new HashMap<>();
            list.forEach(it -> {
                String key = it.getOsType() + "_" + it.getNavbarCode();
                tmp.putIfAbsent(key, it);
            });
            list = new ArrayList<>(tmp.values());
        }
        return succTMulti(list);
    }

    /**
     * @see DynamicNavbarService#queryPage(DynamicNavbarQueryPageRequest)
     */
    @Override
    public TPageResult<DynamicNavbarDTO> queryPage(DynamicNavbarQueryPageRequest request) {
        if (isNotBlank(request.getOsType())) {
            ServiceAssert.isTrue(EnumUtil.inEnum(request.getOsType(), EAppType.class),
                    Errors.Commons.REQUEST_PARAMETER_ERROR);
        }
        List<DynamicNavbarDTO> list = dynamicNavbarRepository.queryPage(request);
        int totalCount = dynamicNavbarRepository.totalCount(request);
        return succTPage(list, request.getPage(), request.getRows(), totalCount);
    }

}
